package cn.cloud.all.security.oauth2.granter;

import cn.cloud.all.security.authentication.exception.InsufficientAuthenticationException;
import cn.cloud.all.security.core.Authentication;
import cn.cloud.all.security.core.context.SecurityContextHolder;
import cn.cloud.all.security.oauth2.provider.*;
import cn.cloud.all.security.oauth2.provider.implicit.ImplicitTokenRequest;
import cn.cloud.all.security.oauth2.provider.token.service.AuthorizationServerTokenServices;
import org.springframework.util.Assert;

public class ImplicitTokenGranter extends AbstractTokenGranter {

    private static final String GRANT_TYPE = "implicit";

    public ImplicitTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
        this(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
    }

    private ImplicitTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
        super(tokenServices, clientDetailsService, requestFactory, grantType);
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest clientToken) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new InsufficientAuthenticationException("There is no currently logged in user");
        }

        Assert.state(clientToken instanceof ImplicitTokenRequest, "An ImplicitTokenRequest is required here. Caller needs to wrap the TokenRequest.");

        OAuth2Request requestForStorage = ((ImplicitTokenRequest) clientToken).getOAuth2Request();

        return new OAuth2Authentication(requestForStorage, authentication);
    }
}
